package ldk.xposed.dexreplace

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.*
import ldk.xposed.dexreplace.ui.AppInfo
import ldk.xposed.dexreplace.ui.AppInfoActivity
import ldk.xposed.dexreplace.ui.InstalledAppAdapter
import ldk.xposed.dexreplace.utils.ShellUtil
import java.io.*
import java.util.*

/**
 * Created by liangdengke on 2018/4/23.
 */
class MainActivity: Activity() {
    companion object {
        private val TAG = "MainActivity"

        fun scanDex(dexFilesFunc: (List<String>, File) -> Unit){
            val dexDir = dexFileDir()
            val dexFiles = dexDir.list().filter { fileName ->  fileName.endsWith(".dex")}
            Log.d(TAG, "dexFiles: $dexFiles")
            dexFilesFunc.invoke(dexFiles, dexDir)
        }

        fun dexFileDir(): File {
            val dexDir = File(Environment.getExternalStorageDirectory(), "dexreplace")
            if (!dexDir.exists()) {
                dexDir.mkdirs()
            }
            return dexDir
        }

        fun loadDexByReplaceDexInfo(info: ReplaceDexInfo?): List<String>{
            if (info == null){
                return Collections.emptyList()
            }
            val replaces = info.dexFilePath
            if (TextUtils.isEmpty(replaces)) return Collections.emptyList()
            return replaces.split(",")
        }
    }

    private lateinit var listView: ListView
    private lateinit var emptyView: TextView

    private var permissionRunnable: Runnable? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        listView = findViewById(R.id.lv_item) as ListView
        emptyView = findViewById(R.id.tv_empty) as TextView
        loadDexInfo()
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
                || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            permissionRunnable?.run()
        }else{
            requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
        }
    }

    override fun onResume() {
        super.onResume()
        val result = ShellUtil.checkSu();
        Log.d(TAG, "result: $result")
    }


    private fun loadDexInfo(){
        emptyView.text = "正在加载已安装应用"
        emptyView.visibility = View.VISIBLE
        listView.adapter = null
        permissionRunnable = Runnable {
            Thread{
                var installedPackages = packageManager.getInstalledPackages(0)
                val server = Server(this)
                val pkgName2ReplaceInfo = server.parseReplaceInfos()
                installedPackages.sortByDescending { it.firstInstallTime }
                installedPackages = installedPackages.filter { it.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0  }
                val infos = installedPackages.map {
                    val info = AppInfo()
                    info.appName = it.applicationInfo.loadLabel(packageManager).toString()
                    info.appIcon = it.applicationInfo.loadIcon(packageManager)
                    info.packagename = it.packageName
                    info.dexReplaceFiles = loadDexByReplaceDexInfo(pkgName2ReplaceInfo[it.packageName])
                    info
                }
                runOnUiThread {
                    val adapter = InstalledAppAdapter(infos)
                    setAdapter(adapter, AdapterView.OnItemClickListener { parent, view, position, id ->
                        val info = infos[position]
                        onInstalledAppClick(info)
                    })
                }
            }.start()
        }
    }

    private fun setAdapter(adapter: ListAdapter, onClickListener: AdapterView.OnItemClickListener){
        emptyView.text = "没有发现InstalledApp"
        listView.adapter = adapter
        listView.onItemClickListener = onClickListener
        emptyView.visibility = if (adapter.count == 0) View.VISIBLE else View.GONE
    }

    private fun onInstalledAppClick(info: AppInfo){
        val intent = Intent(this, AppInfoActivity::class.java)
        intent.putExtra("packageName", info.packagename)
        startActivity(intent)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>?, grantResults: IntArray) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
            permissionRunnable?.run()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == Activity.RESULT_OK){
            loadDexInfo()
        }
    }
}
